package ensemble.samples.custom.sqlformat;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;

/**
 * format sql with param
 *
 * @sampleName sql format
 * @preview preview.png
 * @see javafx.scene.control.Button
 * @highlight
 *
 */
public class SqlFormatApp extends Application {
 

    public Parent createContent() {

        TextArea in = new TextArea("");
        ScrollPane intScrollPane = new ScrollPane();
        intScrollPane.setContent(in);
        intScrollPane.setPrefWidth(800); // Workaround of RT-21495
        intScrollPane.setPrefHeight(245);
        intScrollPane.setFitToWidth(true);
        intScrollPane.setFitToHeight(true);

        TextArea out = new TextArea();

        ScrollPane outScrollPane = new ScrollPane();
        outScrollPane.setContent(out);
        outScrollPane.setPrefHeight(245);
        outScrollPane.setFitToWidth(true);
        outScrollPane.setFitToHeight(true);

        Button showHTMLButton = new Button(new String("sql格式化"));
        showHTMLButton.setOnAction((ActionEvent arg0) -> {
            out.setText(sqlFillParamFormat(in.getText()));
        });
        Button copyButton = new Button("复制到剪切板");
        copyButton.setOnAction((ActionEvent arg0) -> {
            // put it to clipboard
            ClipboardContent cc = new ClipboardContent();
            cc.putString(out.getText());
            Clipboard.getSystemClipboard().setContent(cc);
        });
 
        VBox vRoot = new VBox();
        vRoot.setAlignment(Pos.CENTER);
        vRoot.setSpacing(5);
        vRoot.getChildren().addAll(intScrollPane, showHTMLButton, copyButton, outScrollPane);
 
        return vRoot;
    }
 
    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setScene(new Scene(createContent()));
        primaryStage.show();
    }

    /**
     * Java main for when running without JavaFX launcher
     */
    public static void main(String[] args) {
        launch(args);
    }


    private String sqlFillParamFormat(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        input = input.replace("\r\n", "\n");
        input = input.replace("\r", "");
        if (!input.contains("\n")) {
            return input;
        }
        String[] split = input.split("\n");
        if (split.length != 2) {
            return input;
        }
        String sql = split[0];
        String param = split[1];
        String preparing = "Preparing:";
        String parameters = "Parameters:";
        if (sql.contains(preparing)) {
            sql = getSecondElement(sql.split(preparing));
        }
        if (param.contains(parameters)) {
            param = getSecondElement(param.split(parameters));
        }
        List<String> paramList = getParamList(param);
        for (String s : paramList) {
            if (!sql.contains("?")) {
                return "arguments not match";
            }
            sql = sql.replaceFirst("\\?", s);
        }
        return sql;
    }


    private List<String> getParamList(String param) {
        if (!param.contains(",")) {
            return new ArrayList<>();
        }
        String[] split = param.split(",");
        List<String> result = new ArrayList<>();
        for (String s : split) {
            if (s.contains("(")) {
                String trim = s.substring(0, s.indexOf("(")).trim();
                if (s.contains("(Integer")
                        || s.contains("(Long")
                        || s.contains("(BigDecimal")
                        || s.contains("(Boolean")) {
                    result.add(trim);
                } else  {
                    result.add(String.format("'%s'", trim));
                }
            } else {
                result.add(s.trim());
            }
        }
        return result;
    }

    private String getSecondElement(String[] strings) {
        if (strings == null || strings.length != 2) {
            return "";
        }
        return strings[1];
    }


}